package com.mimosa.common.system.dic;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.mimosa.util.extract.DictionaryExtractor;
import com.mimosa.util.extract.ExpressionExtractor;
import com.mimosa.util.extract.ExtractHit;
import com.mimosa.util.extract.Extractor;

/**
 * 抽取服务对象
 * 
 * @filename ExtractService.java
 * @datetime 2013-9-14 上午10:11:42
 * @author ggeagle
 * 
 */
@Service
@Transactional
public class ExtractService {
	/**
	 * 字典信息类
	 */
	@Resource
	private TDicSettingEntityDao dicSettingDao;
	/**
	 * 字典抽对规则的映射表
	 */
	private Map<DicTypeEnum, Extractor> extractContext = new HashMap<DicTypeEnum, Extractor>();

	public ExtractService() {
		this.extractContext.put(DicTypeEnum.ADDRDIC, new DictionaryExtractor());
		this.extractContext.put(DicTypeEnum.PERSONDIC,
				new DictionaryExtractor());
		this.extractContext.put(DicTypeEnum.ORGDIC, new DictionaryExtractor());
		this.extractContext
				.put(DicTypeEnum.ADDRRULE, new ExpressionExtractor());
		this.extractContext.put(DicTypeEnum.PERSONRULE,
				new ExpressionExtractor());
		this.extractContext.put(DicTypeEnum.ORGRULE, new ExpressionExtractor());
	}

	/**
	 * 根据字典信息进行文本抽取
	 * 
	 * @return
	 */
	public Map<String, Collection<ExtractHit>> extractText(String inputText,
			DicTypeEnum... dicTypeEnum) {
		Map<String, Collection<ExtractHit>> result = new HashMap<String, Collection<ExtractHit>>();
		Extractor extractor = null;
		for (DicTypeEnum typeNum : dicTypeEnum) {
			extractor = this.extractContext.get(typeNum);
			result.put(typeNum.name(), extractor.extract(inputText));
		}
		return result;
	}

	/**
	 * 结合字典和规则对文本进行抽取
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Map<String, Collection<ExtractHit>> extractByDicAndRule(
			String inputText, DicTypeEnum[] dicEnums, DicTypeEnum[] ruleEnums) {
		Map<String, Collection<ExtractHit>> dicResult = this.extractText(
				inputText, dicEnums);
		Map<String, Collection<ExtractHit>> expressionResult = this
				.extractText(inputText, ruleEnums);
		Collection<ExtractHit> dicCollect = dicResult.get(DicTypeEnum.PERSONDIC
				.name());
		Collection<ExtractHit> expCollect = expressionResult
				.get(DicTypeEnum.PERSONRULE.name());
		if (dicCollect != null && expCollect != null) {
			dicResult.put(DicTypeEnum.PERSONDIC.name(),
					CollectionUtils.union(dicCollect, expCollect));
		}
		dicCollect = dicResult.get(DicTypeEnum.ADDRDIC.name());
		expCollect = expressionResult.get(DicTypeEnum.ADDRRULE.name());
		if (dicCollect != null && expCollect != null) {
			dicResult.put(DicTypeEnum.ADDRDIC.name(),
					CollectionUtils.union(dicCollect, expCollect));
		}
		dicCollect = dicResult.get(DicTypeEnum.ORGDIC.name());
		expCollect = expressionResult.get(DicTypeEnum.ORGRULE.name());
		if (dicCollect != null && expCollect != null) {
			dicResult.put(DicTypeEnum.ORGDIC.name(),
					CollectionUtils.union(dicCollect, expCollect));
		}
		return dicResult;
	}

	/**
	 * 初始化节点信息
	 */
	@PostConstruct
	public void initializeExtractor() {
		List<TDicSettingEntity> settingList = null;
		List<String> wordList = null;
		for (Entry<DicTypeEnum, Extractor> entry : this.extractContext
				.entrySet()) {
			settingList = this.dicSettingDao.findBy(
					TDicSettingEntity.PROPERTY_CLASSTYPE,
					String.valueOf(entry.getKey().ordinal()));
			wordList = new ArrayList<String>();
			for (TDicSettingEntity entity : settingList) {
				wordList.add(entity.getDicName());
			}
			entry.getValue().createByDicSettingEntity(wordList);
		}
	}

	/**
	 * 只初始某种类型的字典
	 * 
	 * @param dicTypeEnum
	 */
	public void initializeExtractor(String classType) {
		int dicType = Integer.parseInt(classType);
		DicTypeEnum dicTypeEnum = null;
		if (DicTypeEnum.PERSONDIC.ordinal() == dicType) {
			dicTypeEnum = DicTypeEnum.PERSONDIC;
		} else if (DicTypeEnum.PERSONRULE.ordinal() == dicType) {
			dicTypeEnum = DicTypeEnum.PERSONRULE;
		} else if (DicTypeEnum.ADDRDIC.ordinal() == dicType) {
			dicTypeEnum = DicTypeEnum.ADDRDIC;
		} else if (DicTypeEnum.ADDRRULE.ordinal() == dicType) {
			dicTypeEnum = DicTypeEnum.ADDRRULE;
		} else if (DicTypeEnum.ORGDIC.ordinal() == dicType) {
			dicTypeEnum = DicTypeEnum.ORGDIC;
		} else if (DicTypeEnum.ORGRULE.ordinal() == dicType) {
			dicTypeEnum = DicTypeEnum.ORGRULE;
		}
		if (dicTypeEnum != null) {
			Extractor extractor = this.extractContext.get(dicTypeEnum);
			List<String> wordList = null;
			if (extractor != null) {
				List<TDicSettingEntity> settingList = null;
				settingList = this.dicSettingDao.findBy(
						TDicSettingEntity.PROPERTY_CLASSTYPE,
						String.valueOf(dicTypeEnum.ordinal()));
				wordList = new ArrayList<String>();
				for (TDicSettingEntity entity : settingList) {
					wordList.add(entity.getDicName());
				}
				extractor.createByDicSettingEntity(wordList);
			}
		}
	}
}